package com.eastseeway.radioproject.unlock;

import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.work.WorkInfo;

import com.eastseeway.radioproject.R;
import com.eastseeway.radioproject.RadioApplication;
import com.eastseeway.radioproject.base.BaseActivity;
import com.eastseeway.radioproject.base.Const;
import com.eastseeway.radioproject.databinding.ActivityUnlockBinding;
import com.eastseeway.radioproject.entities.Bean1FromHandle;
import com.eastseeway.radioproject.entities.BeanFromBottomBoard;
import com.eastseeway.radioproject.entities.BeanFromNegativePressureBoard;
import com.eastseeway.radioproject.entities.BeanFromSwitchBoard;
import com.eastseeway.radioproject.entities.BeanOfSplitFile;
import com.eastseeway.radioproject.entities.FirmwareUpdateState;
import com.eastseeway.radioproject.entities.MessageEvent;
import com.eastseeway.radioproject.entities.FirmwareUpdateCommand;
import com.eastseeway.radioproject.entities.UserInfo;
import com.eastseeway.radioproject.entities.VersionBean;
import com.eastseeway.radioproject.main.MainActivity;
import com.eastseeway.radioproject.setting.SettingActivity;
import com.eastseeway.radioproject.utils.ByteUtil;
import com.eastseeway.radioproject.utils.CRC16Check;
import com.eastseeway.radioproject.utils.CommandGenerator;
import com.eastseeway.radioproject.utils.FileSplitUtil;
import com.eastseeway.radioproject.utils.SPHelper;
import com.eastseeway.radioproject.utils.TimeUtils;
import com.eastseeway.radioproject.views.DialogInputPassword;
import com.google.gson.Gson;
import com.tencent.bugly.crashreport.CrashReport;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import struct.StructException;

public class UnlockActivity extends BaseActivity<ActivityUnlockBinding,UnlockViewModel> {
    private VersionBean mVersionBean;
    private Timer mTimer;
    private UserInfo adminInfo;
    private boolean isAcceptCommand1 = true,isTimerRunning = false;
    @Override
    protected int getLayoutId() {
        return R.layout.activity_unlock;
    }

    @Override
    protected void initEvent() {

//        显示当前版本是release 还是debug版本
//        mBinding.unlockInfo.setText("当前版本是： "+(BuildConfig.DEBUG?"debug":"release"));
//          为布局设置ViewModel
        mBinding.setViewmodel(mViewModel);
//        开启计时服务功能
//        startService(new Intent(this, OperationHoursService.class));

//        初始化版本号
//        mBinding.versionCodeTv.setText(BuildConfig.VERSION_NAME);
        mBinding.versionCodeTv.setOnClickListener(v->{
//            checkUpdate();
//            mViewModel.checkFirmwareUpdate();
        });
//          点击设置按钮，弹出输入密码框
        mBinding.setting.setOnClickListener(v->{
            DialogInputPassword dialogInputPassword = new DialogInputPassword(this);
            dialogInputPassword.show();
            dialogInputPassword.setOnConfirmClickListener(password -> {
                    Log.e("12121","userInfo:"+new Gson().toJson(adminInfo));
                    if (adminInfo != null && adminInfo.getPassword().equals(password)) {
                        dialogInputPassword.dismiss();
                        startActivity(new Intent(this, SettingActivity.class));
                    } else {
                        mViewModel.getToastInfo().setValue("密码错误");
                    }
            });
        });

//          点击确认按钮，登录 注释了用户名和密码的验证，直接登录 todo 后期需要放开
        mBinding.unlockConfirm.setOnClickListener(v -> {
            playClickSound();
            mViewModel.queryAdmin().observe(this, userInfo -> {
                if (userInfo != null) {
                    Log.e("12121","userInfo "+new Gson().toJson(userInfo));
                    SPHelper.saveCurrentUserInfo(this,userInfo);
                    startActivity(new Intent(this, MainActivity.class));
                }
            });

//            String username = mViewModel.getUsername().getValue();
//            String password = mViewModel.getPassword().getValue();
//            if (username == null || username.isEmpty()) {
//                Toast.makeText(this, "请输入正确的用户名", Toast.LENGTH_SHORT).show();
//                return;
//            }
//            if (password == null || password.isEmpty()) {
//                Toast.makeText(this, "请输入正确的密码", Toast.LENGTH_SHORT).show();
//                return;
//            }
//             mViewModel.queryUser(username).observe(this, userInfo -> {
//                 if (userInfo == null) {
//                     Toast.makeText(this,"请输入正确的用户名",Toast.LENGTH_SHORT).show();
//                 }else {
//                     if (userInfo.getPassword().equals(password)) {
//                         SPHelper.saveCurrentUserInfo(this,userInfo);
////                         用户登录后，加载当前用户的操作参数
//                         startActivity(new Intent(this, MainActivity.class));
//                     }else {
//                         Toast.makeText(this,"请输入正确的密码",Toast.LENGTH_SHORT).show();
//                     }
//                 }
//             });
        });

    }


    @Override
    protected void loadData() {
//        boolean isNetConnected = mViewModel.isNetConnected();
        new Handler(Looper.getMainLooper()).postDelayed(this::checkUpdate,2000);

//        数据库为空，说明首次使用，首次登录，插入管理员信息
        mViewModel.queryAllUsers().observe(this, userInfos -> {
            if (userInfos.isEmpty()) {
                mViewModel.insertAdmin();
            }
        });
    }

    private void checkUpdate() {
        //        网络是否可用，可用的情况下执行以下操作
        boolean isNetConnected = mViewModel.isNetConnected();
        Log.e("12121","isNetConnected delayed:"+isNetConnected);
        if (isNetConnected) {
//            保存定位信息
//            mViewModel.getLocation();
//            是否需要更新版本
            Log.e("12121","查询是否有硬件更新 ");
            mViewModel.checkFirmwareUpdate();
            CrashReport.initCrashReport(getApplicationContext(), "1fe890aa33", false);
//              上传版本信息
//            mViewModel.uploadVersionInfos("中文1234569663");
        }
//        try {
//            sendMessage(CommandGenerator.commandRequestVersionInfo(Const.ADDRESS_VERSION_INFO_TO_NEGATIVE_PRESSURE));
//            sendMessage(CommandGenerator.command2BottomBoard(Const.ADDRESS_TO_BOTTOM_BOARD, BottomBoardFunctionCode.cmd_bottombrd_read_firmware_info, (short) 0));
//        } catch (StructException e) {
//            throw new RuntimeException(e);
//        }
    }


    @Override
    protected void observeData() {
        mViewModel.getFirmwareUpgradeWorkInfo().observe(this, workInfo -> {
            if (workInfo == null ) {
                return;
            }
            if (!workInfo.getState().isFinished()) {
                return;
            }
            if (workInfo.getState() == WorkInfo.State.SUCCEEDED) {
                String s = workInfo.getOutputData().getString("version_info");
                mViewModel.getFirmwareUpdateState().setValue(FirmwareUpdateState.UPDATING);
                mVersionBean = new Gson().fromJson(s, VersionBean.class);
                Log.e("12121","外部观察到数据： "+new Gson().toJson(mVersionBean));
                processFirmwareFile();
            }
        });

        mViewModel.getFirmwareUpdateState().observe(this, firmwareUpdateState -> {
            mBinding.unlockInfo.setText(firmwareUpdateState.getDescription());
        });

        mViewModel.getToastInfo().observe(this, toastInfo -> {
            Toast.makeText(this, toastInfo, Toast.LENGTH_SHORT).show();
        });

        mViewModel.queryAllVersions().observe(this, versionBeans ->{

        });

        mViewModel.queryAdmin().observe(this, userInfo -> {
            adminInfo = userInfo;
        });
    }

//    处理下载的或通过蓝牙传来的固件
    private void processFirmwareFile(){
        switch (mVersionBean.getSoftStyle()) {
            case "android":
//                        EventBus.getDefault().post(new MessageEvent(Const.EVENT_INSTALL_FLAG, mVersionBean));
                mViewModel.insertVersionInfo(mVersionBean);
                Log.e("12121"," 观察到android程序下载成功  "+new Gson().toJson(mVersionBean));
                RadioApplication.getInstance().getJwsManager().jwsSilentInstallApp(mVersionBean.getSoftFile(), true);
                break;
            case "pressure_board":
//                Log.e("12121"," 观察到负压板下载成功  "+new Gson().toJson(mVersionBean));
//                             启动负压板的升级流程
//                startTestTimeout();
                updateProgress(Const.ADDRESS_FIRMWARE_NEGATIVE_PRESSURE_SET, FirmwareUpdateCommand.cmd_reset, 0);
                break;
            case "bottom_board":
//                Log.e("12121"," 观察到底板下载成功 开始升级 "+new Gson().toJson(mVersionBean));
//                startTestTimeout();
                updateProgress(Const.ADDRESS_FIRMWARE_BOTTOM_SET, FirmwareUpdateCommand.cmd_reset, 0);
                break;
            case "handle1":
//                Log.e("12121","发送手柄1的升级reset ");
//                startTestTimeout();
                updateProgress(Const.ADDRESS_FIRMWARE_HANDLE_1_SET, FirmwareUpdateCommand.cmd_reset, 0);
                break;
            case "handle2":
//                             启动手柄2的升级流程
//                startTestTimeout();
                updateProgress(Const.ADDRESS_FIRMWARE_HANDLE_2_SET, FirmwareUpdateCommand.cmd_reset, 0);
                break;
            case "energy":
//                updateProgress(Const.ADDRESS_FIRMWARE_ENERGY_SET, FirmwareUpdateCommand.cmd_reset, 0);
                break;
            case "switch_board":
//                Log.e("12121"," 观察到转换板下载成功  启动更新"+new Gson().toJson(mVersionBean));
//                startTestTimeout();
                updateProgress(Const.ADDRESS_FIRMWARE_SWITCH_BOARD_SET, FirmwareUpdateCommand.cmd_reset, 0);
                break;
        }
    }

    @Override
    protected Class<UnlockViewModel> getVMClass() {
        return UnlockViewModel.class;
    }

    @Override
    protected void onStop() {
        super.onStop();
        mViewModel.getUsername().setValue("");
        mViewModel.getPassword().setValue("");
        mViewModel.getFirmwareUpdateState().setValue(FirmwareUpdateState.IDLE);
    }

    /*
    *    收到eventbus消息
    */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void OnEvent(MessageEvent messageEvent) {
        int code = messageEvent.getCode();
        if (mViewModel.getFirmwareUpdateState().getValue() == FirmwareUpdateState.UPDATING) {
            if (mVersionBean == null) return;
            if (mVersionBean.getAddress() != code) return;
            int address_set = 0, address_data = 0, mWkStatus = 0;
            times ++;
            Log.e("12121","times:"+times);
            switch (messageEvent.getCode()) {
                case Const.ADDRESS_FROM_HANDLE_1_DATA_1:
                    Bean1FromHandle bean1OfHandle1 = (Bean1FromHandle) messageEvent.getData();
                    mWkStatus = bean1OfHandle1.getWk_status();
                    address_set = Const.ADDRESS_FIRMWARE_HANDLE_1_SET;
                    address_data = Const.ADDRESS_FIRMWARE_HANDLE_1_DATA;
                    break;

                case Const.ADDRESS_FROM_HANDLE_2_DATA_1:
                    Bean1FromHandle bean1FromHandle2 = (Bean1FromHandle) messageEvent.getData();
                    mWkStatus = bean1FromHandle2.getWk_status();
                    address_set = Const.ADDRESS_FIRMWARE_HANDLE_2_SET;
                    address_data = Const.ADDRESS_FIRMWARE_HANDLE_2_DATA;
                    break;
                case Const.ADDRESS_FROM_NEGATIVE_PRESSURE_BOARD:
                    BeanFromNegativePressureBoard beanFromNegativePressureBoard = (BeanFromNegativePressureBoard) messageEvent.getData();
                    mWkStatus = beanFromNegativePressureBoard.getWk_status();
                    address_set = Const.ADDRESS_FIRMWARE_NEGATIVE_PRESSURE_SET;
                    address_data = Const.ADDRESS_FIRMWARE_NEGATIVE_PRESSURE_DATA;
                    break;
                case Const.ADDRESS_FROM_SWITCH_BOARD:
                    BeanFromSwitchBoard beanFromSwitchBoard = (BeanFromSwitchBoard) messageEvent.getData();
                    mWkStatus = beanFromSwitchBoard.getWk_status();
                    address_set = Const.ADDRESS_FIRMWARE_SWITCH_BOARD_SET;
                    address_data = Const.ADDRESS_FIRMWARE_SWITCH_BOARD_DATA;
                    break;
                case Const.ADDRESS_FROM_BOTTOM_BOARD:
                    BeanFromBottomBoard beanFromBottomBoard = (BeanFromBottomBoard) messageEvent.getData();
                    mWkStatus = beanFromBottomBoard.getWk_status();
                    address_set = Const.ADDRESS_FIRMWARE_BOTTOM_SET;
                    address_data = Const.ADDRESS_FIRMWARE_BOTTOM_DATA;
                    break;
            }
//            将本地文件下发给对应的硬件
            File file = new File(mVersionBean.getSoftFile());
            switch (mWkStatus) {
                case 1:
                    if (isAcceptCommand1){
                        Log.e("12121", "接收到1 更新");
                        updateProgress(address_set, FirmwareUpdateCommand.cmd_update, 0);
                        isAcceptCommand1 = false;
                    }

                    break;
                case 2:
                    long length = file.length();
                    Log.e("12121", "接收到2 发送erase size: " + length);
                    updateProgress(address_set, FirmwareUpdateCommand.cmd_erase, (int) Math.ceil(length));
                    break;
                case 3:
                case 4:
                    BeanOfSplitFile beanOfSplitFile = FileSplitUtil.getInstance(mVersionBean.getSoftFile()).getFileBytes(address_data);
                    byte[] fileBytes = beanOfSplitFile.getFileData() ;
                    mBinding.unlockInfo.setText(mVersionBean.getSoftStyle()+" 升级中 "+beanOfSplitFile.getPercent());
                    if (fileBytes != null && fileBytes.length > 0) {
                        sendMessage(fileBytes);
                    } else {
                        try {
                            int i = CRC16Check.CRC16_CCITT_FALSE(mVersionBean.getSoftFile());
                            Log.e("12121", "接收到3 4 发送crc16校验码: " + i);
                            updateProgress(address_set, FirmwareUpdateCommand.cmd_crc, i);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    break;
                case 5:
                    cancelTimeout();
                    Log.e("12121", "接收到5  升级完成 " + mVersionBean.getSoftStyle());
                    isAcceptCommand1 = true;
                    mViewModel.getFirmwareUpdateState().setValue(FirmwareUpdateState.COMPLETED);
                    mVersionBean.setUpdateTime(TimeUtils.getCurrentTime(TimeUtils.FORMAT_DATE_TIME_FULL1));
                    mViewModel.insertVersionInfo(mVersionBean);
                    mVersionBean = null;
                    mViewModel.updateFirmware();
                    break;
                case 6:
                    Log.e("12121", "接收到6 wk_update_err");
                    cancelTimeout();
                    mBinding.unlockInfo.setText(mVersionBean.getSoftStyle() + "升级错误！");
                    mViewModel.getFirmwareUpdateState().setValue(FirmwareUpdateState.FAILED);
                    mVersionBean = null;
//                    mViewModel.updateFirmware();
                    break;
                case 7:
                    Log.e("12121", "接收到7 ");
                    break;
                case 8:
                    Log.e("12121", "接收到8 ");
                    break;
                case 0://收到手柄端发送过来的状态0，因为把手柄拔掉再插上就会复位发0 ，此时就不管手柄了，继续更新其他程序
//                    Log.e("12121", "接收到0 更新2");
//                    mViewModel.updateFirmware();
//                    cancelTimeout();
                    break;
            }
        }
    }

//    private @NonNull VersionBean getVersionBean(MessageEvent messageEvent) {
//        File file = (File) messageEvent.getData();
//        VersionBean mVersionBean = new VersionBean();
//        mVersionBean.setSoftFile(file.getPath());
//        if (file.getPath().contains("switch")) {
//            mVersionBean.setSoftStyle("switch_board");
//        }else if (file.getPath().contains("bottom")) {
//            mVersionBean.setSoftStyle("bottom_board");
//        }else if (file.getPath().contains("pressure")) {
//            mVersionBean.setSoftStyle("pressure_board");
//        }else  if (file.getPath().contains("energy")) {
//            mVersionBean.setSoftStyle("energy_board");
//        }else if (file.getPath().contains("handle1")) {
//            mVersionBean.setSoftStyle("handle1");
//        }else if (file.getPath().contains("handle2")) {
//            mVersionBean.setSoftStyle("handle2");
//        }
//        return mVersionBean;
//    }

    private void updateProgress(int address, FirmwareUpdateCommand cmd_title, int cmd_content){
//        new Handler( Looper.getMainLooper()).postDelayed( () -> {
            try {
                byte[] reset = CommandGenerator.commandUpdateFirmware(address,cmd_title, cmd_content);
//            new Handler(Looper.getMainLooper()).postDelayed(() -> sendMessage(reset),10);
                sendMessage(reset);
            } catch (StructException e) {
                throw new RuntimeException(e);
            }
//        },500);

    }

    private long timeoutFlag,times;
    public void startTestTimeout(){
        if (isTimerRunning) {
            return; // 已经在运行了，不再重复启动
        }
        isTimerRunning = true;
        mTimer = new Timer();
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (timeoutFlag == times) {
                    cancelTimeout();
                    mViewModel.getFirmwareUpdateState().postValue(FirmwareUpdateState.TIMEOUT);
                    mVersionBean = null;
                    timeoutFlag = 0;
                    times = 0;
                }else {
                    timeoutFlag = times;
                }
            }
        }, 10000, 10000);
    }

//    三种情况下会调用：升级完成;升级失败;升级超时
    private void cancelTimeout(){
        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }
        mVersionBean = null;
        timeoutFlag = 0;
        times = 0;
        isTimerRunning = false;
    }

}